import {
	BLE
} from '@/config.js'
import toast from '@/common/toast/index.js'
import {
	ab2arr
} from '@/common/msg-helper.js'
const bluetooth = {
	namespaced: true,
	state: {
		available: false, //蓝牙适配器是否可用
		discovering: false, //是否正在搜索设备
		isInit: false, // 是否初始化
		deviceId: null, //蓝牙ID
		isConn: false, // 是否连接蓝牙
		isListen: false, // 是否在监听
		devices: [], // 设备,
		notifyList: []
	},
	mutations: {
		SET_AVAILABLE(state, value) {
			state.available = value
		},
		SET_DISCOVERING(state, value) {
			state.discovering = value
		},
		SET_ISINIT(state, value) {
			state.isInit = value
		},
		SET_DEVICEID(state, value) {
			state.deviceId = value
		},
		SET_ISCONN(state, value) {
			state.isConn = value
		},
		SET_ISLISTEN(state, value) {
			state.isListen = value
		},
		ADD_DEVICE(state, value) {
			let is_exist = state.devices.some(e => {
				return e.deviceId == value.deviceId
			})
			if (!is_exist) {
				state.devices.push(value)
			}
		},
		RESET_DEVICES(state, value) {
			state.devices = []
		},
		RESET(state) {
			state.available = false //蓝牙适配器是否可用
			state.discovering = false //是否正在搜索设备
			state.isInit = false // 是否初始化
			// state.deviceId = null //蓝牙ID
			state.isConn = false // 是否连接蓝牙
			state.isListen = false // 是否在监听
			state.devices = [] // 搜到的蓝牙设备
		},
		ADD_NOTIFY(state, val) {
			let listLenMax = 50
			let len = state.notifyList.length
			if (len >= listLenMax) {
				state.notifyList.splice(0, 1)
			}
			state.notifyList.push(val)
		}
	},
	actions: {
		/**
		 * 蓝牙初始化
		 */
		BLEInit({
			commit,
			state
		}) {
			commit('RESET')
			return new Promise((resolve, reject) => {
				if (state.isInit) {
					resolve()
					return
				}
				uni.openBluetoothAdapter({
					success: (res) => {
						console.log('openBluetoothAdapter:', res)
						commit('SET_ISINIT', true)
						resolve()
					},
					fail: (err) => {
						console.log('openBluetoothAdapter:', err)
						reject()
					}
				})
			})

		},
		/**
		 * 获取蓝牙状态
		 */
		getState({
			state,
			commit
		}) {
			/**
			 * 未初始化
			 */
			if (!state.isInit) {
				return
			}
			uni.getBluetoothAdapterState({
				success: (res) => {
					console.log('getBluetoothAdapterState:', res)
					commit('SET_AVAILABLE', res.available)
					commit('SET_DISCOVERING', res.discovering)
				},
				fail: (err) => {
					console.log('getBluetoothAdapterState:', err)
				}
			})
		},
		getBLEState({
			commit
		}) {
			uni.onBLEConnectionStateChange(({
				deviceId,
				connected
			}) => {
				console.log('检测的蓝牙状态变化', deviceId, connected)
				commit('SET_ISCONN', connected)
				if (connected) {
					commit('SET_DEVICEID', deviceId)
					toast.success('蓝牙已连接')
				} else {
					commit('SET_DEVICEID', null)
					toast.message('蓝牙已断开')
				}
			})
		},
		/**
		 * 查找BLE蓝牙设备
		 */
		findBLE({
			state,
			commit
		}) {
			/**
			 * 未初始化 不可以 正在搜索 就不执行
			 */
			if (!state.isInit || !state.available || state.discovering) {
				return
			}

			commit('RESET_DEVICES')

			uni.getBluetoothDevices({
				success: (res) => {
					console.log('已搜索到的', res)
					res.devices.forEach(e => {
						if (e.name.indexOf(BLE.NAME) > -1) {
							commit('ADD_DEVICE', e)
						}
					})
				}
			})

			uni.startBluetoothDevicesDiscovery({
				allowDuplicatesKey: true,
				success: (res) => {
					console.log('startBluetoothDevicesDiscovery:', res)
					commit('SET_DISCOVERING', true)
					uni.onBluetoothDeviceFound(res => {
						console.log('onBluetoothDeviceFound:', res)
						res.devices.some(e => {
							if (e.name.indexOf(BLE.NAME) > -1) {
								commit('ADD_DEVICE', e)
							}
						})
					})
				},
				fail: (err) => {
					console.log('搜索蓝牙失败')
				}
			})

		},
		connBLE({
			state,
			commit
		}, id) {
			let deviceId = state.deviceId
			if (id) {
				deviceId = id
			}

			return new Promise((resolve, reject) => {
				if (deviceId == null || state.isConn) {
					reject()
					return
				}
				uni.createBLEConnection({
					deviceId: deviceId,
					timeout: 6000, // 6秒超时
					success: (res) => {
						console.log('createBLEConnection:', res)
						// toast.success('连接成功')
						commit('SET_ISCONN', true)
						commit('SET_DEVICEID', deviceId)

						/**
						 * 兼容苹果
						 */
						uni.getBLEDeviceServices({
							deviceId: deviceId,
							success: () => {
								console.log('获取服务成功')
								uni.getBLEDeviceCharacteristics({
									deviceId: deviceId,
									serviceId: BLE.SERVER_UUID,
									success: () => {
										console.log('获取特征值成')
									}
								})
							}
						})


						resolve(res)
					},
					fail: (err) => {
						commit('SET_DEVICEID', null)
						reject(err)
					}
				})

			})

		},

		closeConn({
			state,
			commit
		}) {
			return new Promise((resolve, reject) => {
				if (state.deviceId == null || !state.isConn) {
					resolve()
					return
				}
				uni.closeBLEConnection({
					deviceId: state.deviceId,
					success: (res) => {
						console.log('断开蓝牙连接')
						commit('SET_ISCONN', false)
						resolve(res)
					},
					fail: (err) => {
						console.log('断开蓝牙连接失败', err)
						reject()
					}
				})
			})

		},
		listenBLE({
			state,
			commit
		}) {
			/**
			 * 未连接 或 已经监听的
			 */
			if (!state.isConn || state.isListen) {
				return
			}
			let deviceId = state.deviceId
			uni.notifyBLECharacteristicValueChange({
				deviceId: deviceId,
				serviceId: BLE.SERVER_UUID,
				characteristicId: BLE.RX,
				state: true,
				success: (res) => {
					commit('SET_ISLISTEN', true)
					uni.onBLECharacteristicValueChange(res => {
						console.log('监听蓝牙特征值变化:', res)
						let arr = ab2arr(res.value)
						commit('ADD_NOTIFY', arr.join(''))
						console.log(arr.join(''))
					})
				},
				fail: (err) => {
					console.log('监听失败', err)
				}
			})
		},

		stopFind({
			commit
		}) {
			return new Promise((resolve, reject) => {
				uni.stopBluetoothDevicesDiscovery({
					success: () => {
						commit('SET_DISCOVERING', false)
						console.log('已停止')
						resolve()
					},
					fail: () => {
						reject()
					}
				})
			})

		},

		sendMsg({
			state
		}, ab) {
			let deviceId = state.deviceId
			return new Promise((resolve, reject) => {
				if (deviceId == null || !state.isConn) {
					// toast.success('发送失败')
					reject()
					return
				}
				console.log('发送消息', deviceId, BLE.SERVER_UUID, BLE.TX)
				uni.writeBLECharacteristicValue({
					deviceId: deviceId,
					serviceId: BLE.SERVER_UUID,
					characteristicId: BLE.TX,
					value: ab,
					success: (res) => {
						console.log('发送成功', res)
						resolve(res) // 数据处理完成
					},
					fail: (err) => {
						console.log('发送失败', err)
						reject(err) // 数据处理出错
					}
				})
			})
		}
	}
}

export default bluetooth
